/******************************************************************************
COPYRIGHT 2012   : ATECH
Layer            : Diagnostic Transport Layer(DTL)-RAW API
Source File Name : Slave_lin1_dtl1.c
Group            : SoftWare Team
Author           : 
Date First Issued: 12/18/2012
Description      :
1. The raw API is operating on PDU level and it is typically used to gateway PDUs
   between CAN and LIN. 
2. Usually, a FIFO is used to buffer PDUs in order to handle the
   different bus speeds.                                                  
******************************************************************************/
#define Slave_lin1_dtl1_c

/* #include */
#include "Slave_lin1_cfg.h"
#include "Slave_lin1_syst.h"
#include "Slave_lin1_dtype.h"
#include "Slave_lin1_htype.h"
#include "Slave_lin1_appl.h"
#include "Slave_lin1_apis.h"
#include <string.h>
/* #define */
#define RAW_TX_FIFO_SIZE    2
#define RAW_RX_FIFO_SIZE    2
/* typedef */
typedef struct
{ 
    LIN1_tenRawTxStatus enStatus;
    l_u8 u8Count;
    l_u8 u8Head;
    l_u8 u8Tail;
    l_u8 au8Buffer[RAW_TX_FIFO_SIZE][8];
    l_bool boEnable;
                
}LIN1_tstRawTx;

typedef struct
{ 
    LIN1_tenRawRxStatus enStatus;
    l_u8 u8Count;
    l_u8 u8Head;
    l_u8 u8Tail;
    l_u8 au8Buffer[RAW_RX_FIFO_SIZE][8];
    l_bool boEnable;
                
}LIN1_tstRawRx;

/* variables */
LIN1_tstRawTx LIN1_stRawTx;
LIN1_tstRawRx LIN1_stRawRx;

/* RAW API */
/*  */


/*****************************************************************************/
/**
 * Function Name: void lin1_ld_init(void)
 * Description:  
 *   
 * Param:   
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_init(void)
 {
	(void)memset(&LIN1_stRawTx, 0x00, sizeof(LIN1_stRawTx));
	(void)memset(&LIN1_stRawRx, 0x00, sizeof(LIN1_stRawRx));
    LIN1_stRawTx.boEnable = L_TRUE;
    LIN1_stRawRx.boEnable = L_TRUE;
    LIN1_stRawTx.enStatus = LIN1_LD_QUEUE_EMPTY;
    LIN1_stRawRx.enStatus = LIN1_LD_NO_DATA;
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_put_raw(l_u8 *u8PDU)
 *
 * Description:   put one send PDU to FIFO
 * 1.if LIN PDU from Tester,call this function directly.  
 * 2.if CAN PDU from Tester,need protocol conversion,then call this function.
 *  
 * Param:   u8PDU:one PDU(8 bytes)
 * Return:  
 * Author:  
 *****************************************************************************/ 
 void lin1_ld_put_raw(l_u8 *pu8PDU)
 {	
    /* FIFO is full */
    if(LIN1_stRawTx.u8Count >= RAW_TX_FIFO_SIZE) return;
           
    LIN1_stRawTx.u8Tail = (l_u8)((LIN1_stRawTx.u8Head + LIN1_stRawTx.u8Count) % RAW_TX_FIFO_SIZE);
    (void)memcpy(LIN1_stRawTx.au8Buffer[LIN1_stRawTx.u8Tail], pu8PDU, 8);
    LIN1_stRawTx.u8Count++;   
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_tx_from_raw(l_u8 *pu8PDU)
 * Description:   put one send PDU into lin driver from FIFO
 *   
 * Param:    u8PDU:one PDU(8 bytes)
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_tx_from_raw(l_u8 *pu8PDU)
 {
    /* FIFO is empty */
    if(LIN1_stRawTx.u8Count == 0)
    {
		(void)memset(pu8PDU, 0x00, 8);
		return;
    }

    (void)memcpy(pu8PDU, LIN1_stRawTx.au8Buffer[LIN1_stRawTx.u8Head], 8);
    LIN1_stRawTx.u8Head = (l_u8)((LIN1_stRawTx.u8Head + 1) % RAW_TX_FIFO_SIZE);
    LIN1_stRawTx.u8Count--;    
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_clear_tx_raw(void)
 * Description:   clear FIFO
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_clear_tx_raw(void)
 {
	LIN1_stRawTx.enStatus = LIN1_LD_QUEUE_EMPTY;
	LIN1_stRawTx.u8Count  = 0;
	LIN1_stRawTx.u8Head   = 0;
	LIN1_stRawTx.u8Tail   = 0;
	(void)memset(LIN1_stRawTx.au8Buffer, 0x00, 8*RAW_TX_FIFO_SIZE);
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_Enable_tx_raw(void)
 * Description:   enable tx
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_Enable_tx_raw(void)
 {
	LIN1_stRawTx.boEnable = L_TRUE;
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_Disable_tx_raw(void)
 * Description:   disable tx
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_Disable_tx_raw(void)
 {
	LIN1_stRawTx.boEnable = L_FALSE;
 }

/*****************************************************************************/
/**
 * Function Name: l_bool lin1_ld_tx_raw_Enable(void)
 * Description:   get tx enable
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 l_bool lin1_ld_tx_raw_Enable(void)
 {
	return LIN1_stRawTx.boEnable;
 }
 
/*****************************************************************************/
/**
 * Function Name: LIN1_tenRawTxStatus lin1_ld_raw_tx_status(void)
 * Description:   get FIFO status
 *   
 * Param:    
 * Return:   status
 * Author:  
 *****************************************************************************/  
 LIN1_tenRawTxStatus lin1_ld_raw_tx_status(void)
 {
    if(LIN1_stRawTx.u8Count == 0)
    {
        LIN1_stRawTx.enStatus = LIN1_LD_QUEUE_EMPTY;    
    }
    else if(LIN1_stRawTx.u8Count >= RAW_TX_FIFO_SIZE)
    {
        LIN1_stRawTx.enStatus = LIN1_LD_QUEUE_FULL;    
    }
    else
    {
        LIN1_stRawTx.enStatus = LIN1_LD_QUEUE_AVAILABLE;    
    }
    
    return LIN1_stRawTx.enStatus;         
 }
 
/*****************************************************************************/
/**
 * Function Name: void lin1_ld_get_raw(l_u8 *u8PDU)
 *
 * Description:   get one recived PDU from FIFO
 *  
 * Param:   u8PDU:one PDU(8 bytes)
 * Return:  
 * Author:  
 *****************************************************************************/ 
 void lin1_ld_get_raw(l_u8 *pu8PDU)
 {
    /* FIFO is empty */
    if(LIN1_stRawRx.u8Count == 0)
    {
		(void)memset(pu8PDU, 0x00, 8);
		return;
    }

    (void)memcpy(pu8PDU, LIN1_stRawRx.au8Buffer[LIN1_stRawRx.u8Head], 8);
    LIN1_stRawRx.u8Head = (l_u8)((LIN1_stRawRx.u8Head + 1) % RAW_RX_FIFO_SIZE);
    LIN1_stRawRx.u8Count--;        
 }
 
 /*****************************************************************************/
/**
 * Function Name: void lin1_ld_rx_into_raw(l_u8 *pu8PDU)
 * Description:   put one recived PDU into FIFO from lin driver
 *   
 * Param:    u8PDU:one PDU(8 bytes)
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_rx_into_raw(l_u8 *pu8PDU)
 {
    /* FIFO is full */
    if(LIN1_stRawRx.u8Count >= RAW_RX_FIFO_SIZE) return;
           
    LIN1_stRawRx.u8Tail = (l_u8)((LIN1_stRawRx.u8Head + LIN1_stRawRx.u8Count) % RAW_RX_FIFO_SIZE);
    (void)memcpy(LIN1_stRawRx.au8Buffer[LIN1_stRawRx.u8Tail], pu8PDU, 8);
    LIN1_stRawRx.u8Count++;    
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_clear_rx_raw(void)
 * Description:   clear FIFO
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_clear_rx_raw(void)
 {
	LIN1_stRawRx.enStatus = LIN1_LD_NO_DATA;
	LIN1_stRawRx.u8Count  = 0;
	LIN1_stRawRx.u8Head   = 0;
	LIN1_stRawRx.u8Tail   = 0;
	(void)memset(LIN1_stRawRx.au8Buffer, 0x00, 8*RAW_RX_FIFO_SIZE);
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_Enable_rx_raw(void)
 * Description:   enable rx
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_Enable_rx_raw(void)
 {
	LIN1_stRawRx.boEnable = L_TRUE;
 }

/*****************************************************************************/
/**
 * Function Name: void lin1_ld_Disable_rx_raw(void)
 * Description:   disable rx
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 void lin1_ld_Disable_rx_raw(void)
 {
	LIN1_stRawRx.boEnable = L_FALSE;
 }

/*****************************************************************************/
/**
 * Function Name: l_bool lin1_ld_rx_raw_Enable(void)
 * Description:   get rx enable
 *   
 * Param:    
 * Return:  
 * Author:  
 *****************************************************************************/
 l_bool lin1_ld_rx_raw_Enable(void)
 {
	return LIN1_stRawRx.boEnable;
 }

/*****************************************************************************/
/**
 * Function Name: LIN1_tenRawRxStatus lin1_ld_raw_rx_status(void)
 * Description:   get FIFO status
 *   
 * Param:    
 * Return:   status
 * Author:  
 *****************************************************************************/  
 LIN1_tenRawRxStatus lin1_ld_raw_rx_status(void)
 {
    if(LIN1_stRawRx.u8Count == 0)
    {
        LIN1_stRawRx.enStatus = LIN1_LD_NO_DATA;    
    }
    else
    {
        LIN1_stRawRx.enStatus = LIN1_LD_DATA_AVAILABLE;    
    }
    
    return LIN1_stRawRx.enStatus;         
 } 
